package manager
{
	import flash.events.KeyboardEvent;
	import flash.utils.Dictionary;
	
	import map.MapInfo;
	
	public class KeyboardManager// extends BaseManager
	{
		private static var keyList:Dictionary;
		
		private static var currentDirection:String = NONE;
		
		public static const W:uint = 87;
		public static const S:uint = 83;
		public static const A:uint = 65;
		public static const D:uint = 68;
		
		public static const DIR_KEYS:Array = [W, S, A, D];
		public static const LEFT:String = "left";
		public static const UP:String = "up";
		public static const RIGHT:String = "right";
		public static const DOWN:String = "down";
		public static const UP_LEFT:String = "up_left";
		public static const UP_RIGHT:String = "up_right";
		public static const DOWN_LEFT:String = "down_left";
		public static const DOWN_RIGHT:String = "down_right";
		public static const NONE:String = "none";
		
		public function KeyboardManager()
		{
			super();
			keyList = new Dictionary();
		}
		
		public function keyDownHandler(event:KeyboardEvent):void{
			keyList[event.keyCode] = true;
			movePlayer(event.keyCode);
		}
		
		public function keyUpHandler(event:KeyboardEvent):void{
			keyList[event.keyCode] = false;
			stopPlayer(event.keyCode);
		}
		
		/**
		 * 键盘按下，人物在相应方向上移动
		 * 目前仅支持WSAD键移动人物
		 * @param keyCode
		 */		
		public function movePlayer(keyCode:uint):void {
			if (!isDirKeyDown())//方向键已被释放, 则不需要继续移动玩家
				return;
			
			var direction:String = NONE;
			
			//检查除了当前按下的方向键外还有几个方向键被按下
			var dirKeyArr:Array = queryDirKey();
			var index:uint = dirKeyArr.indexOf(keyCode);
			dirKeyArr.splice(index, 1);
			
			var length:uint = dirKeyArr.length;
			if(length == 0) {
				//只有当前的方向键被按下，直接计算方向
				direction = calDirection(keyCode);
			} else if (length == 1) {
				//除了当前方向键，还有另外的方向键被按下
				direction = calDirection(dirKeyArr[0], keyCode);
			} else if (length == 2) {
				//四键同时按下，判定为非法操作
				direction = NONE;
			} else if (length == 3) {
				//四键同时按下，判定为非法操作
				direction = NONE
			}
			//currentDirKey = keyCode;
			/*if (direction == currentDirection) 
				return;*/
			
			//			DebugLayer.print(direction);
			
			currentDirection = direction;
			movePlayerForward(currentDirection);
		}
		
		//判断某键是否为方向键
		private function isDirKey(key:uint):Boolean {
			var index:int = DIR_KEYS.indexOf(key);
			return index != -1;
		}
		
		//查找按下的方向键
		private function queryDirKey():Array {
			var dirKeyArr:Array = [];
			for (var key:Object in keyList) {
				if (isDirKey(key as uint) && keyList[key]) {
					dirKeyArr.push(key);
				}
			}
			return dirKeyArr;
		}
		
		//由给定的2个方向键值判定人物移动方向
		private function calDirection(key1:uint, key2:uint = 0 ):String {
			if (key1 == W && key2 == A) return  UP_LEFT;
			if (key1 == W && key2 == D) return  UP_RIGHT;
			if (key1 == S && key2 == A) return  DOWN_LEFT;
			if (key1 == S && key2 == D) return  DOWN_RIGHT;
			
			if (key1 == A && key2 == W) return  UP_LEFT;
			if (key1 == A && key2 == S) return  DOWN_LEFT;
			if (key1 == D && key2 == W) return  UP_RIGHT;
			if (key1 == D && key2 == S) return  DOWN_RIGHT;
			
			if (key1 == W && key2 == 0) return  UP;
			if (key1 == S && key2 == 0) return  DOWN;
			if (key1 == A && key2 == 0) return  LEFT;
			if (key1 == D && key2 == 0) return  RIGHT;
			
			return NONE;
		}
		
		//让人物沿某方向运动，先计算该方向上的终点，再移动人物
		private function movePlayerForward(direction:String):void {
			if(null == SceneManager.getInstance().mainScene)
				return;
			switch(direction)
			{
				case UP:
					SceneManager.getInstance().mainScene.dy -= MapInfo.keyboardMoveSpeedY;
					break;
				case DOWN:
					SceneManager.getInstance().mainScene.dy += MapInfo.keyboardMoveSpeedY;
					break;
				case LEFT:
					SceneManager.getInstance().mainScene.dx -= MapInfo.keyboardMoveSpeedX;
					break;
				case RIGHT:
					SceneManager.getInstance().mainScene.dx += MapInfo.keyboardMoveSpeedX;
					break;
				
				case UP_LEFT:
					SceneManager.getInstance().mainScene.dx -= MapInfo.keyboardMoveSpeedX;
					SceneManager.getInstance().mainScene.dy -= MapInfo.keyboardMoveSpeedY;
					break;
				case UP_RIGHT:
					SceneManager.getInstance().mainScene.dx += MapInfo.keyboardMoveSpeedX;
					SceneManager.getInstance().mainScene.dy -= MapInfo.keyboardMoveSpeedY;
					break;
				case DOWN_LEFT:
					SceneManager.getInstance().mainScene.dx -= MapInfo.keyboardMoveSpeedX;
					SceneManager.getInstance().mainScene.dy += MapInfo.keyboardMoveSpeedY;
					break;
				case DOWN_RIGHT:
					SceneManager.getInstance().mainScene.dx += MapInfo.keyboardMoveSpeedX;
					SceneManager.getInstance().mainScene.dy += MapInfo.keyboardMoveSpeedY;
					break;
			}
			
			//trace("======"+SceneManager.getInstance().mainScene.dx+"==============="+SceneManager.getInstance().mainScene.dy+"============")
			
			/*if (direction == NONE) {
				gamePlayer.stopWalk();
				return;
			}
			var startPoint:Point = new Point(gamePlayer.x, gamePlayer.y);
			var endPoint:Point = gameMask.calEndPoint(startPoint, direction);
			gamePlayer.moveTo(endPoint.x, endPoint.y);*/
		}
		
		/**
		 * 方向键释放后，人物站定
		 * 将人物移动的终点设为人物当前的坐标点，可让人物停止移动
		 */		
		public function stopPlayer(keyCode:uint):void {
			if (!isDirKey(keyCode))//释放的键为非方向键
				return;
			
			var dirKeyArr:Array = queryDirKey();
			var length:uint = dirKeyArr.length;
			if (length == 0) {
				//currentDirKey = 0;
				currentDirection = NONE;
			} else if (length == 1){
				currentDirection = calDirection(dirKeyArr[0]);
			} else if (length == 2) {
				currentDirection = calDirection(dirKeyArr[0], dirKeyArr[1]);
			} else if (length == 3) {
				currentDirection = NONE;
			}
			
			movePlayerForward(currentDirection);
		}
		
		
		/**
		 * 是否有方向移动键被按下，按下后角色开始移动
		 * 判断WSAD键的状态, 其中如有任何一键为按下，则返回true；
		 * @return 
		 */		
		public static function isDirKeyDown():Boolean {
			var result:Object = isKeyDown(W) || isKeyDown(S) || isKeyDown(A) || isKeyDown(D);
			return result ? result : false;
		}
		
		public static function isKeyDown(key:int):Boolean {
			return keyList[key];//true, false, undefined
		}
	}
}